import { App, defineAsyncComponent, h, render, isReactive, toRaw } from "vue";
import { cloneDeep, isString, mergeWith } from "lodash";
import CpcDrawer from "./CpcDrawer.vue";
import CpcDrawerLoading from "./CpcDrawerLoading.vue";

const components: any = {};
const modules = import.meta.glob("./child/**/*.vue");
Object.keys(modules).forEach(key => {
    const sI = key.lastIndexOf("/") + 1;
    const eI = key.lastIndexOf(".");
    const name = key.substring(sI, eI);
    components[name] = modules[key];
});

const styleTypeMap: any = {
    left: {
        left: 0,
        top: 0,
        width: "30%",
        height: "100%",
    },

    top: {
        left: 0,
        top: 0,
        width: "100%",
        height: "30%",
    },
    right: {
        right: 0,
        top: 0,
        width: "30%",
        height: "100%",
    },
    bottom: {
        left: 0,
        bottom: 0,
        width: "100%",
        height: "30%",
    },
    center: {
        left: "50%",
        top: "50%",
        transform: "translate(-50%,-50%)",
    },
    full: {
        left: 0,
        top: 0,
        width: "100%",
        height: "100%",
    },
};
export interface ICpcComponentConfig {
    component: string; // 组件名
    data?: any; // 数据
    callBack?: any; // 回调函数
}
export interface ICpcDrawerConfig {
    title?: string; // 标题名称
    isShowCloseIcon?: boolean; // 是否显示关闭按钮
    isShowMask?: boolean; // 是否显示遮罩
    isMaskEvent?: boolean; // 点击遮罩是否允许关闭
    zIndex?: number; // 最外层的z-index
    styleType?: "left" | "top" | "right" | "bottom" | "center" | "full";
    styles?: any; // 覆盖模态框的样式
}
const defaultConfig: ICpcDrawerConfig = {
    isShowCloseIcon: true,
    isShowMask: true,
    isMaskEvent: true,
    zIndex: 9,
    styleType: "left",
};

export class CpcDrawerCtrl {
    private static _app: App | null = null;

    public static install(app: App, options?: { [key: string]: any }) {
        this._app = app;
    }

    public static open(config: ICpcComponentConfig, drawerConfig?: ICpcDrawerConfig) {
        if (!this._app) {
            console.error("请先在main.ts中 app.use(GlobalDrawerCtrl)");
            return;
        }
        const box = document.createElement("div");
        if (!box) {
            return;
        }
        const drawerProps: any = mergeWith(cloneDeep(defaultConfig), drawerConfig);
        drawerProps.styles = mergeWith(cloneDeep(styleTypeMap[drawerProps.styleType]), drawerProps.styles);
        box.style.position = "fixed";
        box.style.top = "0";
        box.style.left = "0";
        box.style.zIndex = `${drawerProps?.zIndex}`;
        document.body.appendChild(box);
        drawerProps.close = () => {
            document.body.removeChild(box);
        };
        if (isReactive(config.data)) {
            config.data = toRaw(config.data);
        }
        const componentProps = {
            datas: cloneDeep(config.data),
            close() {
                document.body.removeChild(box);
            },
            callBack(data: any) {
                if (config.callBack) {
                    config.callBack(data, this.close);
                }
            },
        };
        let component: any = config.component;
        if (isString(config.component)) {
            component = defineAsyncComponent(components[config.component]);
        }
        const vm = h(CpcDrawer, drawerProps, { default: () => h(component, componentProps) });
        // 这里很重要，关联app上下文
        vm.appContext = this._app._context;
        render(vm, box);
    }
}
